package com.ruoyi.common.core.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;


/**
 * [java8的时间工具类]
 *
 */
public class LocalDateTimeUtils {

    public static final String YYYYMMDD = "YYYYMMDD";
    public static final String YYYYMMDDhh = "YYYYMMDDhh";
    public static final String YYYYMMDDhhmm = "YYYYMMDDhhmm";
    public static final String YYYYMMDDhhmmss = "yyyy-MM-dd HH:mm:ss";

    // 两个日期的天数(end > now为正数)
    // + 超期  - 未超期
    public static long daysDifference(LocalDate start, LocalDate end) {
//        Duration duration = Duration.between(start, end);
//        long days = duration.toDays();
        return ChronoUnit.DAYS.between(start, end);
    }

    // 两个日期的分钟数(end > now为正数)
    // + 超期  - 未超期
    public static Long minusDifference(LocalDateTime start, LocalDateTime end) {
        Duration duration = Duration.between(start, end);
        return duration.toMinutes(); // 相差的分钟数
    }

    /**
     * [把字符串的日期转换成LocalDateTime]
     * @param localDateTimeStr
     * @return
     */
    public static LocalDateTime parseLocalDateTime(String localDateTimeStr) {
        if(StringUtils.isEmpty(localDateTimeStr)) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(localDateTimeStr, fmt);
    }

    /**
     * [把LocalDateTime的日期转换成字符串]
     * @param time
     * @return
     */
    public static String formatLocalDateTime(LocalDateTime time) {
        if(time == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return time.format(fmt);
    }

    /**
     * [把LocalDateTime的日期转换成字符串]
     * @param time
     * @return
     */
    public static String formatLocalDateTime3(LocalDateTime time) {
        if(time == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return time.format(fmt);
    }

    /**
     * [把字符串的日期转换成LocalDateTime]
     * @param localDateTimeStr
     * @return
     */
    public static LocalDateTime parseLocalDateTime2(String localDateTimeStr) {
        if(StringUtils.isEmpty(localDateTimeStr)) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
        return LocalDateTime.parse(localDateTimeStr, formatter);
    }

    /**
     * [把LocalDateTime的日期转换成字符串]
     * @param time
     * @return
     */
    public static String formatLocalDateTime4(LocalDateTime time) {
        if(time == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        return time.format(fmt);
    }
    public static String formatLocalDateTime5(LocalDateTime time,String pattern) {
        if(time == null) {
            return "";
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pattern);
        return time.format(fmt);
    }

    /**
     * [把long的日期转换成字符串]
     * @param timestamp
     * @return
     */
    public static String formatLocalDate(long timestamp) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
        return localDateTime.format(fmt);
    }

    /**
     * [把long的日期转换成字符串]
     * @param timestamp
     * @return
     */
    public static String formatLocalDateTime(long timestamp) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
        return localDateTime.format(fmt);
    }

    /**
     * [把long的日期转换成字符串]
     * @param timestamp
     * @return
     */
    public static String formatLocalTime(long timestamp) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
        timestamp = getWeeHoursDate() + timestamp;
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
        return localDateTime.format(fmt);
    }

    /**
     * [把LocalDateTime的日期转换成字符串]
     * @param time
     * @return
     */
    public static String formatLocalDateTime2(LocalDateTime time) {
        if(time == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        return time.format(fmt);
    }

    /**
     * [按照time的时间往前延 Minutes 分钟的时间数据]
     * @return
     */
    public static LocalDateTime getBeforeMinutesTime(LocalDateTime time, Integer minutes) {
        return time.plusMinutes(minutes);
    }

    /**
     * 向前推移 monthNum 个月
     * @param monthNum
     * @return
     */
    public static List<String> moveBackMonth(Integer monthNum) {
        LocalDate today = LocalDate.now();

        List<String> monthList = new ArrayList<>();
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM");

        for(int i = monthNum - 1; i >= 0; i--){
            LocalDate localDate = today.minusMonths(i);
            String ss = localDate.format(fmt);
            monthList.add(ss);
        }

        return monthList;
    }

    /**
     * [校验checkTime是否在startTime~endTime时间范围内]
     * @param startTime
     * @param endTime
     * @param checkTime
     * @return
     */
    public static boolean checkTimeRange(LocalDateTime startTime, LocalDateTime endTime, LocalDateTime checkTime) {
        if((checkTime.isAfter(startTime) || checkTime.isEqual(startTime)) && (checkTime.isBefore(endTime) || checkTime.isEqual(endTime))) {
            return true;
        }
        return false;
    }


    /**
     * [判断时分是对等的]
     * @param time
     * @return
     */
    public static boolean equalsHouseMinus(LocalDateTime time, String value) {
        if(time == null) {
            return false;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm");
        String format = time.format(fmt);
        if(format.equals(value)) {
            return true;
        }
        return false;
    }

    /**
     * 获取月的开始日期和结束日期
     * @param month 2023-12
     * @return
     */
    public static List<String> monthStartEndTime(String month) {

        if(StringUtils.isEmpty(month)) {
            return new ArrayList<>();
        }

        List<String> monthTime = new ArrayList<>(2);
        String startTime = (month + "-01 00:00:00");
        monthTime.add(startTime);

        LocalDateTime localDateTime = parseLocalDateTime(startTime);
        assert localDateTime != null;
        LocalDateTime adjustInto = (LocalDateTime) YearMonth.from(localDateTime).atEndOfMonth().adjustInto(localDateTime);
        monthTime.add((formatLocalDateTime3(adjustInto)) + " 23:59:59");

        return monthTime;

    }

    /**
     * 获取天的开始日期和结束日期
     * @param day 2023-12-12
     * @return
     */
    public static List<String> dayStartEndTime(String day) {

        if(StringUtils.isEmpty(day)) {
            return new ArrayList<>();
        }

        List<String> monthTime = new ArrayList<>(2);
        String startTime = (day + " 00:00:00");
        monthTime.add(startTime);
        monthTime.add(day + " 23:59:59");
        return monthTime;

    }

    /**
     * 获取特定格式的时间数据
     * @return
     */
    public static String getDayFormat(Date date, String dateFormat) {

        if(date == null) {
            return null;
        }

        // 创建一个SimpleDateFormat对象，定义日期格式
        SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);

        return formatter.format(date);
    }

    /**
     * 获取当前月的所有日期 2023-12
     * @param yearMonth
     */
    public static List<String> currentMonthDay(String yearMonth) {

        List<String> allDay = new ArrayList<>();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 获取年份
        String[] split = yearMonth.split("-");
        int year = Integer.parseInt(split[0]);

        // 获取月份
        int month = Integer.parseInt(split[1]);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year );
        calendar.set(Calendar.MONTH, month - 1 );
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int max = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        for (int i = 0; i < max; i++) {
            calendar.set(Calendar.DAY_OF_MONTH, i + 1);
            String day = sdf.format(calendar.getTime());
            allDay.add(day);
        }
        return allDay;
    }

    /**
     * 获取当日凌晨时间的毫秒值
     * @return 日期毫秒值
     */
    public static long getWeeHoursDate(){
        long nowTime =System.currentTimeMillis();
        return nowTime - ((nowTime + TimeZone.getDefault().getRawOffset()) % (24 * 60 * 60 * 1000L));
    }

}
